home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 …ember: Reference Library / Dev.CD Dec 00 RL Disk 1.toast / pc / technical documentation / develop / develop issue 28 / develop issue 28 code / sketch / source / main / imaging.c < prev    next >
Encoding:
Text File  |  1996-08-04  |  9.7 KB  |  425 lines

  1. // -------------------------------------------------------------------
  2. // Imaging.c
  3. //
  4. // -------------------------------------------------------------------
  5.  
  6. #include "Structs.h"
  7.  
  8. #include "Imaging.h"
  9.  
  10. #include "DocumentADT.h"
  11. #include "DocumentHelpers.h"
  12.  
  13. #include "ElementADT.h"
  14. #include "ElementHelpers.h"
  15.  
  16. #include "WindowUtils.h"
  17.  
  18. #include "Assertion.h"
  19.  
  20. // -------------------------------------------------------------------
  21.  
  22. static void SaveDrawingState        (WindowPtr window, DrawingState *state);
  23. static void RestoreDrawingState        (WindowPtr window, DrawingState *state);
  24.  
  25. static void DrawEveryElement        (DocumentReference document, ElementList list);
  26. static void DrawElement                (ElementReference element);
  27.  
  28. // -------------------------------------------------------------------
  29.  
  30. void IMDraw(DocumentReference document)
  31. {    
  32.     GrafPtr            currentPort;
  33.     
  34.     // for off-screen drawing
  35.     
  36.     CGrafPtr        windowPort;
  37.     GDHandle        windowDevice;
  38.     QDErr            error;
  39.     GWorldPtr        offscreen        = NULL;
  40.     PixMapHandle    offscreenPixMap    = nil;
  41.     Boolean            success;
  42.     
  43.     Rect            sourceRect;
  44.     Rect            destinationRect;
  45.     
  46.     BitMap *        srcMap;
  47.     BitMap *        destMap;
  48.  
  49.     WindowPtr        window = GetDocumentWindow(document);
  50.     Rect            portRect;
  51.     
  52.     RGBColor        saveBackColor;
  53.     RGBColor        saveForeColor;
  54.     RGBColor        black    = {0x0000, 0x0000, 0x0000};
  55.     RGBColor        white   = {0xFFFF, 0xFFFF, 0xFFFF};
  56.     
  57.     GetPort(¤tPort);
  58.     SetPort(window);
  59.     
  60.     GetWindowPortRect(window, &portRect);
  61.     
  62.     GetGWorld(&windowPort, &windowDevice);    // Save the window port
  63.     
  64.     // Make an offscreen GWorld
  65.     
  66.     error = NewGWorld(&offscreen, 0, &portRect, nil, nil, 0);
  67.     
  68.     if (error != noErr || offscreen == nil)
  69.     {
  70.         SysBeep(2);
  71.         DebugStr("\pCan't create new GWorld.");
  72.         goto CleanUp;
  73.     }
  74.         
  75.     SetGWorld(offscreen, nil);
  76.     
  77.     offscreenPixMap = GetGWorldPixMap(offscreen);
  78.     
  79.     success = LockPixels(offscreenPixMap);
  80.     
  81.     if (!success)
  82.     {
  83.         SetGWorld(windowPort, windowDevice);
  84.         SysBeep(2);
  85.         DebugStr("\pCan't create LockPixels on new GWorld.");
  86.         goto CleanUp;
  87.     }
  88.         
  89.     PenNormal();
  90.     RGBForeColor(&black);
  91.     RGBBackColor(&white);
  92.     EraseRect(&offscreen->portRect);
  93.         
  94.     DrawEveryElement(document, GetDocumentElementList(document));
  95.     
  96.     // Go back to the window port
  97.     
  98.     SetGWorld(windowPort, windowDevice);
  99.     
  100.     sourceRect         = offscreen->portRect;
  101.     destinationRect = portRect;
  102.     
  103.     srcMap    = (BitMap *) *GetGWorldPixMap(offscreen);    
  104.     destMap    = (BitMap *) &(((GrafPtr) window)->portBits);
  105.  
  106.     GetForeColor(&saveForeColor);
  107.     GetBackColor(&saveBackColor);
  108.  
  109.     RGBForeColor(&black);
  110.     RGBBackColor(&white);
  111.  
  112.     CopyBits(srcMap, destMap, &sourceRect, &destinationRect, srcCopy, nil);
  113.     
  114.     if (QDError() != noErr)
  115.     {
  116.         SysBeep(2);
  117.         DebugStr("\pCopyBits() returned and error.");
  118.  
  119.     }
  120.         
  121.     RGBBackColor(&saveBackColor);
  122.     RGBForeColor(&saveForeColor);
  123.     
  124. CleanUp:
  125.     
  126.     if (offscreenPixMap != nil)
  127.         UnlockPixels(offscreenPixMap);
  128.         
  129.     if (offscreen != NULL)
  130.         DisposeGWorld(offscreen);
  131.     
  132.     SetPort(currentPort);
  133. }
  134.  
  135. // -------------------------------------------------------------------
  136.  
  137. void IMDelete(DocumentReference document, ElementReference element)
  138. {    
  139.     DestroyElement(element);
  140.     IMDraw(document);
  141. }
  142.  
  143. // -------------------------------------------------------------------
  144.  
  145. void ResizeElementData(DocumentReference document, ElementReference element, Rect newBounds)
  146. {
  147.     Rect    oldBounds;
  148.     
  149.     oldBounds = GetElementBoundingBox(element);
  150.     
  151.     // --- resize depending on shape -----------------------------------------
  152.  
  153.     switch (GetElementType(element))
  154.     {
  155.         case kQDLine:
  156.             ResizeOpenEndedObject(document, element, newBounds);
  157.             break;
  158.                 
  159.         case kQDRect:
  160.         case kQDRoundRect:
  161.         case kQDOval:
  162.             ResizeClosedObject(document, element, newBounds);
  163.             break;
  164.                     
  165.         case kQDPolygon:
  166.             ResizePolygon(document, element, newBounds);
  167.             break;
  168.                 
  169.         case kGroup:
  170.             ResizeGroup(document, element, newBounds);
  171.             break;
  172.                 
  173.         default:
  174.                 Assert(kAssertAlways, "Resizing is disabled for this type of object.");
  175.                 break;
  176.     }        
  177. }
  178.  
  179. // -----------------------------------------------------------------------------------------
  180.  
  181. void ResizeOpenEndedObject(DocumentReference document, ElementReference element, Rect newBounds)
  182. {
  183. #pragma unused (document, element, newBounds)
  184.  
  185. }
  186.  
  187.  
  188. // -----------------------------------------------------------------------------------------
  189.  
  190. void ResizeClosedObject(DocumentReference document, ElementReference element, Rect newBounds)
  191. {
  192. #pragma unused (document)
  193.  
  194.     SetElementBoundingBox(element, newBounds);
  195. }
  196.  
  197.  
  198. // -----------------------------------------------------------------------------------------
  199.  
  200. void ResizePolygon(DocumentReference document, ElementReference element, Rect newBounds)
  201. {
  202. #pragma unused (document, element, newBounds)
  203.  
  204. }
  205.  
  206.  
  207. // -----------------------------------------------------------------------------------------
  208.  
  209. void ResizeGroup(DocumentReference document, ElementReference element, Rect newBounds)
  210. {
  211. #pragma unused (document, element, newBounds)
  212.  
  213. }
  214.  
  215.  
  216. // -----------------------------------------------------------------------------------------
  217.  
  218. void MoveElementData(DocumentReference document, ElementReference element, short newTop, short newLeft)
  219. {
  220.     Rect            elementRect;
  221.     short            deltaH;
  222.     short            deltaV;
  223.     
  224.     elementRect = GetElementBoundingBox(element);    
  225.     
  226.     deltaV        = newTop  - elementRect.top;
  227.     deltaH        = newLeft - elementRect.left;
  228.             
  229.     OffsetElementData(document, element, deltaH, deltaV);
  230. }
  231.  
  232. // -----------------------------------------------------------------------------------------
  233.  
  234. void OffsetElementData(DocumentReference document, ElementReference element, short deltaH, short deltaV)
  235. {
  236.     ElementReference        subElement;
  237.     Rect                    elementRect;
  238.     PolyHandle                polygon;
  239.     Point                     begin;
  240.     Point                    end;
  241.     
  242.     if (deltaH || deltaV)
  243.     {
  244.         // --- go recursive if we have to ----------------------------------------
  245.     
  246.         if (GetElementType(element) == kGroup)
  247.             for (subElement = GetFirstSubElement(element); subElement != nil; subElement = GetNextElement(subElement))
  248.                 OffsetElementData(document, subElement, deltaH, deltaV);
  249.             
  250.         // --- offset bounding box -----------------------------------------------
  251.     
  252.         elementRect = GetElementBoundingBox(element);                                // extract current element rectangle
  253.         OffsetRect(&elementRect, deltaH, deltaV);                                        // offset for new position
  254.         SetElementBoundingBox(element, elementRect);                                    // set new bounding box
  255.         
  256.         // --- offset dependent data ---------------------------------------------
  257.     
  258.         switch (GetElementType(element))
  259.         {
  260.             case kQDLine:
  261.                 begin = GetElementLineBeginPoint(element);
  262.                 end   = GetElementLineEndPoint(element);
  263.  
  264.                 begin.h += deltaH;
  265.                 end.h    += deltaH;
  266.                 begin.v += deltaV;
  267.                 end.v    += deltaV;
  268.                 
  269.                 SetElementLineBeginPoint(element, begin);
  270.                 SetElementLineEndPoint(element, end);
  271.                 
  272.                 break;
  273.         
  274.             case kQDPolygon:
  275.                 polygon = GetElementPolygon(element);
  276.                 if (polygon != nil)
  277.                 {    
  278.                     OffsetPoly(polygon, deltaH, deltaV);
  279.                 }                    
  280.                 break;
  281.                     
  282.             default:
  283.                 // do nothing special for other types
  284.                 break;
  285.         }        
  286.     }
  287. }
  288.  
  289. // -----------------------------------------------------------------------------------------
  290.  
  291. static void DrawEveryElement(DocumentReference document, ElementList list)
  292. {
  293.     ElementReference element;
  294.  
  295.     for (element = GetFirstElement(list); element != nil; element = GetNextElement(element))
  296.     {
  297.         if (GetElementType(element) != kGroup)
  298.         {
  299.             DrawElement(element);
  300.         }
  301.         else
  302.         {
  303.             DrawEveryElement(document, GetElementSubElementList(element));
  304.         }
  305.     }
  306. }
  307.  
  308. // -----------------------------------------------------------------------------------------
  309.  
  310. static void DrawElement(ElementReference element)
  311. {
  312.     ElementType    elementType;
  313.     Rect        elementBounds;
  314.     Point        p1;
  315.     Point        p2;
  316.     
  317.     RGBColor    strokeColor;
  318.     RGBColor    fillColor;
  319.     short        penWidth;
  320.     short        penHeight;
  321.         
  322.     strokeColor = GetElementStrokeColor(element);
  323.     fillColor   = GetElementFillColor(element);
  324.     penWidth    = GetElementStrokePenWidth(element);
  325.     penHeight   = GetElementStrokePenHeight(element);
  326.     
  327.     elementType = GetElementType(element);
  328.     elementBounds = GetElementBoundingBox(element);
  329.     
  330.     PenSize(penWidth, penHeight);
  331.  
  332.     switch (elementType)
  333.     {
  334.         case kQDLine:
  335.             RGBForeColor(&strokeColor);
  336.             p1 = GetElementLineBeginPoint(element);
  337.             p2 = GetElementLineEndPoint(element);
  338.             MoveTo(p1.h, p1.v);
  339.             LineTo(p2.h, p2.v);
  340.             break;
  341.  
  342.         case kQDRect:
  343.             RGBForeColor(&fillColor);
  344.             FillRect(&elementBounds, &qd.black);
  345.             
  346.             RGBForeColor(&strokeColor);
  347.             FrameRect(&elementBounds);
  348.             break;
  349.     
  350.         case kQDOval:
  351.             RGBForeColor(&fillColor);
  352.             FillOval(&elementBounds, &qd.black);
  353.  
  354.             RGBForeColor(&strokeColor);
  355.             FrameOval(&elementBounds);
  356.             break;
  357.     
  358.         case kQDPolygon:
  359.             RGBForeColor(&fillColor);
  360.             FillPoly(GetElementPolygon(element), &qd.black);
  361.  
  362.             RGBForeColor(&strokeColor);
  363.             FramePoly(GetElementPolygon(element));
  364.             break;
  365.     
  366.         case kQDRoundRect:
  367.             p1 = GetElementRoundRectOvalSize(element);
  368.  
  369.             RGBForeColor(&fillColor);
  370.             FillRoundRect(&elementBounds,  p1.h, p1.v, &qd.black);
  371.  
  372.             RGBForeColor(&strokeColor);
  373.             FrameRoundRect(&elementBounds, p1.h, p1.v);;
  374.             break;
  375.     
  376.         default:
  377.             RGBForeColor(&fillColor);
  378.             FillRect(&elementBounds, &qd.black);
  379.  
  380.             RGBForeColor(&strokeColor);
  381.             FrameRect(&elementBounds);
  382.             break;
  383.     }
  384.  
  385. }
  386.  
  387. // -----------------------------------------------------------------------------------------
  388.  
  389. static void SaveDrawingState(WindowPtr window, DrawingState *state)
  390. {
  391.     GrafPtr        curPort;
  392.     
  393.     GetPort(&curPort);
  394.     SetPort(window);
  395.  
  396.     GetPenState(&(state->penState));
  397.     
  398.     GetForeColor(&(state->foreColor));
  399.     GetBackColor(&(state->backColor));
  400.  
  401.     SetPort(curPort);
  402. }
  403.  
  404. // -----------------------------------------------------------------------------------------
  405.  
  406. static void RestoreDrawingState(WindowPtr window, DrawingState *state)
  407. {
  408.     GrafPtr        curPort;
  409.     
  410.     GetPort(&curPort);
  411.     SetPort(window);
  412.     
  413.     SetPenState(&(state->penState));
  414.     
  415.     RGBForeColor(&(state->foreColor));
  416.     RGBBackColor(&(state->backColor));
  417.  
  418.     SetPort(curPort);
  419. }
  420.  
  421. // -----------------------------------------------------------------------------------------
  422.  
  423.  
  424.  
  425.